package peer.gui;
import java.util.ArrayList;

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

import common.Util;


public class SearchResultModel implements TableModel
{
	private class SearchResult
	{
		String name;
		long size;
		int peers;
		String hashcode;
		
		public SearchResult(String name, long size, int peers, String hascode)
		{
			this.name = name;
			this.size = size;
			this.peers = peers;
			this.hashcode = hascode;
		}

		public void incrementPeers()
		{
			peers++;
		}
	}
	
	String query;
	
	ArrayList<SearchResult> data = new ArrayList<SearchResult>();
	String[] columnNames = {"Filename", "Size", "Peers", "Hashcode"}; //add seeders at a later stage
	Class[] columnClasses = {String.class, String.class, Integer.class, String.class};
	
	TableModelListener listener;

	public SearchResultModel() {}
	
	public SearchResultModel(String query)
	{
		this.query = query;
	}
	
	public void addTableModelListener(TableModelListener listener)
	{
		this.listener = listener;

	}

	//returns the String class (everything displayed is a string)
	public Class<?> getColumnClass(int i)
	{
		return columnClasses[i];
	}

	public int getColumnCount()
	{
		return columnNames.length;
	}

	public String getColumnName(int i)
	{
		return columnNames[i];
	}

	public int getRowCount()
	{
		return data.size();
	}

	public Object getValueAt(int row, int column)
	{
		switch (column)
		{
		case 0:
			return data.get(row).name; //normally have break following, but they're unreachable with the return
		case 1:
			return Util.getNiceFileSize(data.get(row).size);
		case 2:
			return new Integer(data.get(row).peers);
		case 3:
			return data.get(row).hashcode;
		default:
			break;
		}
		return null;
	}
	
	public String getNameAt(int row)
	{
		return data.get(row).name;
	}
	
	public long getSizeAt(int row)
	{
		return data.get(row).size;
	}
	
	public int getPeersAt(int row)
	{
		return data.get(row).peers;
	}
	
	public String getHashcodeAt(int row)
	{
		return data.get(row).hashcode;
	}

	public boolean isCellEditable(int row, int column)
	{
		return false;
	}

	public void removeTableModelListener(TableModelListener l)
	{
		listener = null;
	}

	//no values can be changed by the user, so we don't need anything here
	public void setValueAt(Object arg0, int arg1, int arg2)
	{
		// TODO Auto-generated method stub

	}

	//all that the GUI will ever do with this is add results and update the number of peers when more peers
	//are found (and clear it when a new search is done)
	public void addResult(String name, long size, String hashcode)
	{
		//see if the result is already in the list
		boolean found = false;
		int i = 0;
		while (!found && i < data.size())
		{
			if(data.get(i).hashcode.equals(hashcode))
			{
				data.get(i).incrementPeers();
				if(listener != null)
				{
					listener.tableChanged(new TableModelEvent(this, i));
				}
				found = true;
			}
			i++;
		}
		if(!found)
		{
			data.add(new SearchResult(name, size, 1, hashcode));
			if(listener != null) //when this result model is being displayed by the gui, update it
			{
				listener.tableChanged(new TableModelEvent(this, data.size(), data.size(), TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
			}
		}
	}
	
	public void incrementPeers(String hashcode)
	{
		boolean found = false;
		int i = 0;
		while (!found && i < data.size())
		{
			if(data.get(i).hashcode.equals(hashcode))
			{
				data.get(i).incrementPeers();
				listener.tableChanged(new TableModelEvent(this, i));
			}
		}
	}
	
	public void clear()
	{
		data.clear();
		listener.tableChanged(new TableModelEvent(this));
	}

	public String getQuery()
	{
		return query;
	}
}
